<template>
  <el-table
    border
    ref="dragTable"
    :data="tableData"
    style="width: 100%"
    class="cell-no-padding"
    :row-key="rowKey"
    :cell-style="cellStyle"
    @selectionChange="handleSelectionChange"
    @row-dblclick="dblclick"
  >
    <!-- 拖拽图标 -->
    <el-table-column v-if="dragRow" width="55" prop="fieldId">
      <font-icon code="&#xe693;" font-size="24" class="inline-block cursor-pointer ml-4 mt-1" />
    </el-table-column>
    <el-table-column v-if="multiple" type="selection" width="55" />
    <el-table-column :fixed="fixed" v-else type="index" width="55" align="center">
      <template #header> 序号 </template>
    </el-table-column>
    <el-table-column
      v-for="tItem in tableOption"
      v-bind="tItem"
      :key="tItem.key"
      :prop="tItem.key"
      :width="tItem.width"
    >
      <template #default="scope">
        <div v-if="tItem.key === 'options' && tItem.optionList" class="options">
          <el-button
            v-for="(OItem, Oindex) in tItem.optionList"
            v-show="btnVisible(OItem, scope)"
            :key="Oindex"
            :type="OItem.type"
            :link="OItem.link"
            :round="OItem.round"
            :circle="OItem.circle"
            :plain="OItem.plain"
            :class="OItem.class"
            :disabled="OItem.disabled ? OItem.disabled(scope.row) : false"
            @click="OItem.fn(scope, tItem)"
          >
            {{ OItem.name }}
          </el-button>
        </div>
        <el-switch
          v-else-if="tItem.valueType === 'boolean'"
          v-model="scope.row[tItem.key]"
          :disabled="!tItem.canChange"
          @change="(val) => tItem.change(scope.row, val)"
        />

        <!--需要展示带颜色的文字 colorWord类型-->
        <div
          v-else-if="tItem.valueType === 'colorWord'"
          :style="{
            color: tItem.colorRender !== null ? tItem.colorRender(scope.row[tItem.key], tItem) : '',
          }"
        >
          {{ tItem.customRender(scope.row[tItem.key], tItem) }}
        </div>

        <div
          v-else-if="tItem.valueType === 'enum'"
          :style="{
            color: scope.row[tItem.key] !== null ? tItem.enum[scope.row[tItem.key]]?.color : '',
          }"
        >
          {{ scope.row[tItem.key] !== null ? tItem.enum[scope.row[tItem.key]].text : '' }}
        </div>
        <div v-else-if="tItem.valueType === 'custom'" class="cell-item">
          {{ tItem.customRender(scope.row[tItem.key]) }}
        </div>
        <div v-else-if="tItem.valueType === 'checkBox'" class="cell-item">
          <el-checkbox
            v-model="scope.row[tItem.key]"
            :disabled="disabled || scope.row.disabled"
            @change="checkChange(scope.row)"
          ></el-checkbox>
        </div>
        <div v-else-if="tItem.valueType === 'select'" class="cell-item">
          <el-select
            v-model="scope.row[tItem.key]"
            :placeholder="tItem.placeholder ?? '请选择'"
            :size="tItem.size ?? 'small'"
            :disabled="disabled"
            :multiple="tItem.multiple ?? false"
            :filterable="tItem.filterable ?? false"
          >
            <el-option
              v-for="item in tItem.option"
              :key="item.value"
              :label="item.label"
              :value="item[tItem.optionBindField ?? 'value']"
            />
          </el-select>
        </div>

        <div v-else-if="tItem.valueType === 'tag'" class="cell-item">
          <el-tag class="dot" :type="tItem.getTag(scope.row[tItem.key]).type">
            {{ tItem.getTag(scope.row[tItem.key]).text }}
          </el-tag>
        </div>
        <div
          v-else-if="
            (typeof tItem.valueType == 'function' ? tItem.valueType(scope.row) : tItem.valueType) ==
            'input'
          "
          class="cell-item"
        >
          <el-input v-model="scope.row[tItem.key]" :placeholder="tItem.placeholder"></el-input>
        </div>

        <el-date-picker
          v-else-if="tItem.valueType === 'date-picker'"
          :style="{ width: `${tItem.width ? tItem.width : `${230}px`}` }"
          v-model="scope.row[tItem.key]"
          clearable
          :type="tItem.datePickerType ?? 'daterange'"
          :value-format="tItem.valueFormat ? tItem.valueFormat : 'YYYY-MM-DD HH:mm:ss'"
          range-separator="至"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
        />

        <div v-else-if="tItem.valueType === 'popover'" class="cell-item">
          <el-popover
            :placement="tItem.placement ?? 'top'"
            :trigger="tItem.trigger ?? 'hover'"
            :effect="tItem.effect ?? 'light'"
          >
            <div> {{ tItem.customRender(scope.row[tItem.key], tItem) }}</div>
            <template #reference>
              <div> {{ scope.row[tItem.key] }}</div>
            </template>
          </el-popover>
        </div>

        <div v-else class="cell-item">
          {{ scope.row[tItem.key] }}
        </div>
      </template>
    </el-table-column>
    <template v-if="multiOptions && multiOptions.length">
      <el-table-column
        v-for="tItem2 in multiOptions"
        v-bind="tItem2"
        :key="tItem2.key"
        :prop="tItem2.key"
      >
        <el-table-column
          v-for="tItem in tItem2.list"
          v-bind="tItem"
          :key="tItem.key"
          :prop="tItem.key"
        >
          <template #default="scope">
            <div v-if="tItem.key === 'options' && tItem.optionList" class="options">
              <el-button
                v-for="(OItem, Oindex) in tItem.optionList"
                v-show="btnVisible(OItem, scope)"
                :key="Oindex"
                :type="OItem.type"
                :link="OItem.link"
                :round="OItem.round"
                :circle="OItem.circle"
                :plain="OItem.plain"
                :class="OItem.class"
                :disabled="OItem.disabled ? OItem.disabled(scope.row) : false"
                @click="OItem.fn(scope, tItem)"
              >
                {{ OItem.name }}
              </el-button>
            </div>
            <el-switch
              v-else-if="tItem.valueType === 'boolean'"
              v-model="scope.row[tItem.key]"
              :disabled="!tItem.canChange"
              @change="(val) => tItem.change(scope.row, val)"
            />

            <!--需要展示带颜色的文字 colorWord类型-->
            <div
              v-else-if="tItem.valueType === 'colorWord'"
              :style="{
                color:
                  tItem.colorRender !== null ? tItem.colorRender(scope.row[tItem.key], tItem) : '',
              }"
            >
              {{ tItem.customRender(scope.row[tItem.key], tItem) }}
            </div>

            <div
              v-else-if="tItem.valueType === 'enum'"
              :style="{
                color: scope.row[tItem.key] !== null ? tItem.enum[scope.row[tItem.key]]?.color : '',
              }"
            >
              {{ scope.row[tItem.key] !== null ? tItem.enum[scope.row[tItem.key]].text : '' }}
            </div>
            <div v-else-if="tItem.valueType === 'custom'" class="cell-item">
              {{ tItem.customRender(scope.row[tItem.key]) }}
            </div>
            <div v-else-if="tItem.valueType === 'checkBox'" class="cell-item">
              <el-checkbox v-model="scope.row[tItem.key]" :disabled="disabled"></el-checkbox>
            </div>
            <div v-else-if="tItem.valueType === 'select'" class="cell-item">
              <el-select
                v-model="scope.row[tItem.key]"
                :placeholder="tItem.placeholder ?? '请选择'"
                :size="tItem.size ?? 'small'"
                :disabled="disabled"
              >
                <el-option
                  v-for="item in tItem.option"
                  :key="item.value"
                  :label="item.label"
                  :value="item[tItem.optionBindField ?? 'value']"
                />
              </el-select>
            </div>

            <div v-else-if="tItem.valueType === 'tag'" class="cell-item">
              <el-tag class="dot" :type="tItem.getTag(scope.row[tItem.key]).type">
                {{ tItem.getTag(scope.row[tItem.key]).text }}
              </el-tag>
            </div>
            <div
              v-else-if="
                (typeof tItem.valueType == 'function'
                  ? tItem.valueType(scope.row)
                  : tItem.valueType) == 'input'
              "
              class="cell-item"
            >
              <el-input v-model="scope.row[tItem.key]" :placeholder="tItem.placeholder"></el-input>
            </div>

            <el-date-picker
              v-else-if="tItem.valueType === 'date-picker'"
              :style="{ width: `${tItem.width ? tItem.width : `${230}px`}` }"
              v-model="scope.row[tItem.key]"
              clearable
              :type="tItem.datePickerType ?? 'daterange'"
              :value-format="tItem.valueFormat ? tItem.valueFormat : 'YYYY-MM-DD HH:mm:ss'"
              range-separator="至"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
            />

            <div v-else-if="tItem.valueType === 'popover'" class="cell-item">
              <el-popover :placement="tItem.placement ?? 'top'" :trigger="tItem.trigger ?? 'hover'">
                <div> {{ tItem.customRender(scope.row[tItem.key], tItem) }}</div>
                <template #reference>
                  <div> {{ scope.row[tItem.key] }}</div>
                </template>
              </el-popover>
            </div>

            <div v-else class="cell-item">
              {{ scope.row[tItem.key] }}
            </div>
          </template>
        </el-table-column>
      </el-table-column>
    </template>
  </el-table>
</template>

<script>
  import Sortable from 'sortablejs';
  export default {
    components: {},
    props: {
      multiOptions: {
        //多级表头
        type: Array,
        required: false,
        default: () => [],
      },
      multiple: {
        type: Boolean,
        required: false,
        default: false,
      },
      tableData: {
        type: Array,
        required: true,
        default: () => [],
      },
      tableOption: {
        type: Array,
        required: true,
        default: () => [],
      },
      fixed: {
        type: Boolean,
        required: false,
        default: false,
      },
      disabled: {
        type: Boolean,
        required: false,
        default: false,
      },
      rowKey: {
        type: String,
        required: false,
        default: '',
      },
      dragRow: {
        type: Boolean,
        required: false,
        default: false,
      },
      dragPrefix: {
        type: String,
        required: false,
        default: '',
      },
      cellStyle: {
        type: Object,
        required: false,
        default: () => {},
      },
    },
    emits: ['multipleSelectionChange', 'dragRow', 'checkChange', 'dblclick'],
    data() {
      return {
        multipleSelection: [],
      };
    },
    computed: {
      btnVisible() {
        return (item, scope) => {
          if (item.btnType || scope.row.operation) {
            if (item.btnType === 'add' && scope.row.operation == 'add') {
              return true;
            } else {
              return false;
            }
          } else {
            if (!item.key) {
              return true;
            } else if (item.key === 'inclusion' && [0, 2].includes(scope.row.status)) {
              return true;
            } else if (item.key === 'notInclusion' && [0, 1].includes(scope.row.status)) {
              return true;
            } else if (item.key === 'edit' && ['1', '4'].includes(scope.row.state)) {
              return true;
            } else {
              return false;
            }
          }
        };
      },
    },
    watch: {},
    created() {},
    mounted() {},
    methods: {
      handleSelectionChange(val) {
        this.multipleSelection = val;
        this.$emit('multipleSelectionChange', val);
      },
      setSort() {
        let _that = this;
        const html = this.dragPrefix + '.el-table__body-wrapper tbody';
        const el = document.querySelector(html);
        _that.sortable = Sortable.create(el, {
          onStart: function (e) {
            e.oldIndex;
          },
          //结束拖拽
          onEnd: function (obj) {
            _that.$emit('dragRow', obj);
          },
        });
      },
      checkChange(val) {
        this.$emit('checkChange', val);
      },
      dblclick(val) {
        this.$emit('dblclick', val);
      },
    },
  };
</script>

<style lang="scss">
  .custom-table {
    .el-table th.el-table__cell {
      background-color: #f2f5f5;
      color: #333333;
      height: 50px;
    }
    .cell-item {
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }
  .cell-no-padding.el-table {
    th {
      .cell {
        padding: 0 5px;
      }
    }
    .el-table__body {
      tr {
        .cell {
          padding: 0 3px;
        }
      }
    }
  }
</style>

<style lang="scss" scoped>
  .el-table {
    //--el-table-border-color: #fff;
    :deep(td.el-table__cell, th.el-table__cell.is-leaf) {
      border-bottom: 1px solid #eee;
    }
  }

  .dot {
    position: relative;
    padding-left: 15px;
    font-weight: 500;
    color: rgba(3, 169, 244, 1);
    background: rgba(3, 169, 244, 0.1);
    &.el-tag--success {
      color: rgba(76, 175, 80, 1);
      background: rgba(76, 175, 80, 0.1);
    }
    &.el-tag--warning {
      color: rgba(239, 108, 0, 1);
      background: rgba(239, 108, 0, 0.1);
    }
    &.el-tag--danger {
      color: rgba(211, 47, 47, 1);
      background: rgba(211, 47, 47, 0.1);
    }
    &::before {
      content: '';
      width: 3px;
      height: 3px;
      background-color: currentColor;
      border-radius: 50%;
      position: absolute;
      left: 8px;
      top: 50%;
      transform: translateY(-50%);
    }
  }
</style>
